#include "MainFrame.h"
#include <stdlib.h>
void on_VideoPlayFinish(void*);


MainFrame::MainFrame(cameraDriver* _CameraDriver) :
	wxFrame(nullptr, wxID_ANY, wxT("相机采集"),
		wxDefaultPosition, wxSize(1050, 600)),
	CameraDriver(_CameraDriver),
	playEngine(nullptr),
	mStatus(MainFrameStatus::Init),
	remoteHandle(this)
{
	wxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
	wxSizer* deviceSizer = new wxBoxSizer(wxVERTICAL);
	wxSizer* collectBarSizer = new wxBoxSizer(wxHORIZONTAL);
	wxSizer* playBarSizer = new wxBoxSizer(wxHORIZONTAL);
	wxSizer* videoSizer = new wxBoxSizer(wxVERTICAL);
	wxSizer* cameraControlSizer = new wxBoxSizer(wxVERTICAL);
	wxSizer* fileHandleModeSizer=new wxBoxSizer(wxHORIZONTAL);
	
	radioPlayMode=new wxRadioButton(this,(wxWindowID)MainFrameID::radioPlayMode,wxT("播放模式"));
	radioAnalyMode=new wxRadioButton(this,(wxWindowID)MainFrameID::radioAnalyMode,wxT("分析模式"));
	btnCameraShot=new wxButton(this,(wxWindowID)MainFrameID::btnCameraShot,wxT("开始拍摄"));
	btnRefreshDevice = new wxButton(this, (wxWindowID)MainFrameID::btnRefreshDevice, wxT("刷新设备"));
	btnOpenCloseDevice = new wxButton(this, (wxWindowID)MainFrameID::btnOpenCloseDevice, wxT("打开设备"));
	btnControlCollege = new wxButton(this, (wxWindowID)MainFrameID::btnControlCollege, wxT("开始存图"));
	btnVideoPlayControl = new wxButton(this, (wxWindowID)MainFrameID::btnVideoPlayControl, wxT("开始播放"));
	txtInf = new wxStaticText(this, wxID_ANY, wxT("准备就绪"),wxDefaultPosition,wxDefaultSize);
	dirpSaveDir = new wxDirPickerCtrl(this, (wxWindowID)MainFrameID::dirpSaveDir,wxEmptyString,wxString(),wxDefaultPosition,wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST);
	panelCameraDisplay = new ImageDisplay(this,wxID_ANY,&remoteHandle);
	panelCameraControl = new CameraControl(this);
	listDeviceList = new wxListCtrl(this, (wxWindowID)MainFrameID::listDeviceList, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
	sliderPlayControl = new wxSlider(this, (wxWindowID)MainFrameID::sliderPlayControl, 10, 0, 100);
	sliderPlaySpeedControl = new wxSlider(this, (wxWindowID)MainFrameID::sliderPlaySpeedControl, 0, -2, 2);
	InfUpdate = new wxTimer(this, (wxWindowID)MainFrameID::InfUpdate);
	btnUpdateDir = new wxButton(this, (wxWindowID)MainFrameID::btnUpdateDir, wxT("刷新目录"));
	txtPlayFrameCount = new wxStaticText(this, (wxWindowID)MainFrameID::txtPlayFrameCount, wxT("../.."));
	listVideoList = new wxListCtrl(this, (wxWindowID)MainFrameID::listVideoList, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
	txtPlayFrameInf = new wxStaticText(this, (wxWindowID)MainFrameID::txtPlayFrameInf, wxT("30FPS"));
	btnOutputToBMP = new wxButton(this, (wxWindowID)MainFrameID::btnOutputToBMP, wxT("导出为BMP"));
	analyBar=new AnalyControlBar(this,panelCameraDisplay);
	btnRemoteSetting=new wxButton(this,(int)MainFrameID::btnRemoteSetting,wxT("服务器设置"));
	cboxRemoteMonitor=new wxCheckBox(this,(int)MainFrameID::cboxRemoteMonitor,wxT("远程同步"));
	msgFileTransfer=new wxMessageDialog(this,wxT("文件传输中"),wxT("文件传输"),wxICON_INFORMATION);

	deviceSizer->Add(btnRefreshDevice, wxSizerFlags(1).Border().Expand());
	deviceSizer->Add(listDeviceList, wxSizerFlags(8).Border().Expand());
	deviceSizer->Add(panelCameraControl, wxSizerFlags(9).Border().Expand());
	deviceSizer->Add(btnOpenCloseDevice, wxSizerFlags(1).Border().Expand());
	deviceSizer->Add(btnCameraShot,wxSizerFlags(1).Border().Expand());
	collectBarSizer->Add(dirpSaveDir, wxSizerFlags(8).Border());
	collectBarSizer->Add(btnUpdateDir, wxSizerFlags(1).Border());
	collectBarSizer->Add(btnControlCollege, wxSizerFlags(1).Border());
	collectBarSizer->Add(cboxRemoteMonitor,wxSizerFlags(1).CenterVertical());
	playBarSizer->Add(btnVideoPlayControl, wxSizerFlags(1).Border());
	playBarSizer->Add(sliderPlayControl, wxSizerFlags(9).CenterVertical());
	playBarSizer->Add(txtPlayFrameCount, wxSizerFlags(0).CenterVertical());
	playBarSizer->Add(sliderPlaySpeedControl, wxSizerFlags(2).Border().CenterVertical());
	playBarSizer->Add(txtPlayFrameInf, wxSizerFlags(0).CenterVertical());
	videoSizer->Add(collectBarSizer,wxSizerFlags(1).Border().Expand());
	videoSizer->Add(panelCameraDisplay, wxSizerFlags(15).Border().Expand());
	videoSizer->Add(playBarSizer, wxSizerFlags(1).Border().Expand());
	fileHandleModeSizer->Add(radioPlayMode,wxSizerFlags(1));
	fileHandleModeSizer->Add(radioAnalyMode,wxSizerFlags(1));
	cameraControlSizer->Add(txtInf, wxSizerFlags(1).Border().Expand());
	cameraControlSizer->Add(analyBar,wxSizerFlags(4).Border().Expand());
	cameraControlSizer->Add(listVideoList, wxSizerFlags(8).Border().Expand());
	cameraControlSizer->Add(btnOutputToBMP, wxSizerFlags(1).Border().Expand());
	cameraControlSizer->Add(btnRemoteSetting,wxSizerFlags(1).Border().Expand());
	cameraControlSizer->Add(fileHandleModeSizer,wxSizerFlags(1).Expand().Border());
	topSizer->Add(deviceSizer,wxSizerFlags().Proportion(0).Border().Expand());
	topSizer->Add(videoSizer,wxSizerFlags().Proportion(8).Border().Expand());
	topSizer->Add(cameraControlSizer, wxSizerFlags().Proportion(4).Border().Expand());
	

	SetSizerAndFit(topSizer);
	panelCameraDisplay->SetBackgroundColour(wxColour(0, 0, 0));

	playEngine = new ImagePlayEngine(this,(int)MainFrameID::playEngine,&saveFile, panelCameraDisplay, sliderPlayControl);
	playEngine->SetPlayFinishHandle(&on_VideoPlayFinish, this);
	btnControlCollege->Enable(false);
	btnUpdateDir->Enable(false);
	listDeviceList->SetMaxSize(wxSize(250,2000));
	remoteHandle.SetCameraContrlHandler(panelCameraControl); //设置相机控制类
	const char* homePath=std::getenv("HOME");
	if(homePath!=nullptr)
		dirpSaveDir->SetPath(homePath);
	
	CheckConfigFile();

	setStatus(MainFrameStatus::Init);
}

MainFrame::~MainFrame()
{
	if (InfUpdate->IsRunning())
		InfUpdate->Stop();
	if (!playEngine)
		delete playEngine;
	delete panelCameraDisplay;
}

bool MainFrame::setStatus(MainFrameStatus newStatus)
{
	switch (newStatus)
	{
	case MainFrameStatus::Init:
		{
			Bind(wxEVT_RADIOBUTTON,&MainFrame::on_radioPlayMode_click,this,(int)MainFrameID::radioPlayMode);
			Bind(wxEVT_RADIOBUTTON,&MainFrame::on_radioAnalyMode_click,this,(int)MainFrameID::radioAnalyMode);
			Bind(wxEVT_BUTTON,&MainFrame::on_btnCameraShot_click,this,(int)MainFrameID::btnCameraShot);
			Bind(wxEVT_BUTTON, &MainFrame::on_btnRefreshDevice_click, this, (int)MainFrameID::btnRefreshDevice);
			Bind(wxEVT_BUTTON, &MainFrame::on_btnOpenCloseDevice_click, this, (int)MainFrameID::btnOpenCloseDevice);
			Bind(wxEVT_LIST_ITEM_SELECTED, &MainFrame::on_listDeviceList_select, this, (int)MainFrameID::listDeviceList);
			Bind(wxEVT_DIRPICKER_CHANGED, &MainFrame::on_dirpSaveDir_change, this, (int)MainFrameID::dirpSaveDir);
			Bind(wxEVT_BUTTON, &MainFrame::on_btnControlCollege_click, this, (int)MainFrameID::btnControlCollege);
			Bind(wxEVT_TIMER, &MainFrame::on_InfUpdate_timeout, this, (int)MainFrameID::InfUpdate);
			Bind(wxEVT_BUTTON, &MainFrame::on_btnVideoPlayControl_click, this, (int)MainFrameID::btnVideoPlayControl);
			Bind(wxEVT_LIST_ITEM_SELECTED, &MainFrame::on_listVideoList_select, this, (int)MainFrameID::listVideoList);
			Bind(wxEVT_BUTTON, &MainFrame::on_btnUpdateDir_click, this, (int)MainFrameID::btnUpdateDir);
			Bind(wxEVT_SCROLL_CHANGED, &MainFrame::on_sliderPlaySpeedControl_change, this, (int)MainFrameID::sliderPlaySpeedControl);
			Bind(wxEVT_SCROLL_CHANGED, &MainFrame::on_sliderPlayControl_change, this, (int)MainFrameID::sliderPlayControl);
			Bind(wxEVT_BUTTON,&MainFrame::on_btnOutputToBMP_click,this,(int)MainFrameID::btnOutputToBMP);
			Bind(wxEVT_BUTTON,&MainFrame::on_btnRemoteSetting_click,this,(int)MainFrameID::btnRemoteSetting);
			Bind(wxEVT_CHECKBOX,&MainFrame::on_cboxRemoteMonitor_click,this,(int)MainFrameID::cboxRemoteMonitor);
			Bind(EVT_GETDEVICESTATUS,&MainFrame::on_RemoteGetStatus,this,wxID_ANY);
			Bind(EVT_COMMAND_INITDEVICE,&MainFrame::on_RemoteInitDevice,this,wxID_ANY);
			Bind(EVT_COMMAND_STARTSHOT,&MainFrame::on_RemoteStartShot,this,wxID_ANY);
			Bind(EVT_COMMAND_STARTSAVE,&MainFrame::on_RemoteStartSave,this,wxID_ANY);
			Bind(EVT_COMMAND_STOPSHOT,&MainFrame::on_RemoteStopShot,this,wxID_ANY);
			Bind(EVT_COMMAND_STOPSAVE,&MainFrame::on_RemoteStopSave,this,wxID_ANY);
			Bind(EVT_COMMAND_GETCAMERAPARA,&MainFrame::on_RemoteGetCameraPara,this,wxID_ANY);
			Bind(EVT_COMMAND_ENABLE_TRIGGER,&MainFrame::on_RemoteEnableTriggerMode,this,wxID_ANY);
			Bind(EVT_COMMAND_DISABLE_TRIGGER,&MainFrame::on_RemoteDisableTriggerMode,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_EXPOSETIME,&MainFrame::on_RemoteSetExposeTime,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_IMAGEHEIGHT,&MainFrame::on_RemoteSetImageHeight,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_IMAGEWIDTH,&MainFrame::on_RemoteSetImageWidth,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_IMAGEOFFSETX,&MainFrame::on_RemoteSetOffsetX,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_IMAGEOFFSETY,&MainFrame::on_RemoteSetOffsetY,this,wxID_ANY);
			Bind(EVT_COMMAND_SET_FRAMERATE,&MainFrame::on_RemoteSetFrameRate,this,wxID_ANY);
			Bind(EVT_COMMAND_FILETRANSFER_ENABLE,&MainFrame::on_RemoteFileTransferEnable,this,wxID_ANY);
			Bind(EVT_COMMAND_FILETRANSFER_DISABLE,&MainFrame::on_RemoteFileTransferDisable,this,wxID_ANY);
			Bind(EVT_COMMAND_FILETRANSFER_REQUEST,&MainFrame::on_RemoteFileTransferRequest,this,wxID_ANY);
			setStatus(MainFrameStatus::Noting);
			return true;
		}
		break;
	case MainFrameStatus::ImageCollege:
		{
			if(mStatus!=MainFrameStatus::CameraRunning)
			{
				wxMessageBox("相机尚未打开，禁止启动图像采集",wxT("内部错误"),wxICON_ERROR | wxOK);
				return false;
			}
			panelCameraControl->disableSubFunOnCameraRunning();
			InfUpdate->Start(500);
			btnCameraShot->SetLabelText(wxT("停止拍摄"));
		}
		break;
	case MainFrameStatus::VideoPlay:
		{
			if(currentVideoFile.length()==0 || dirpSaveDir->GetPath().IsEmpty())
			{
				wxMessageBox(wxT("没有选择播放文件"),wxT("错误"),wxICON_ERROR | wxOK);
				return false;
			}
			if(mStatus!=MainFrameStatus::Noting)
			{
				wxMessageBox(wxT("请先关闭所有相机再启动播放功能"),wxT("错误"),wxICON_ERROR | wxOK);
				return false;
			}
			btnVideoPlayControl->SetLabelText(wxT("暂停播放"));
			sliderPlayControl->Enable(true);
			InfUpdate->Start(500);
		}
		break;
	case MainFrameStatus::CameraRunning:
		{
			switch (mStatus) //状态上下文判断
			{
			case MainFrameStatus::ImageCollege:
				{
					btnCameraShot->SetLabelText(wxT("开始拍摄"));
					panelCameraControl->enableSubFunOnCameraNotRunning();
					InfUpdate->Stop();
				}
				break;
			case MainFrameStatus::Noting:
				{
					panelCameraControl->Enable(true);
					btnCameraShot->Enable(true);
					listVideoList->Enable(false);
				}
				break;
			default:
				wxMessageBox(wxT("请先暂停其他功能"),wxT("操作错误"),wxICON_INFORMATION | wxOK);
				return false;
				break;
			}
		}
		break;
	case MainFrameStatus::ImageAnalysis:
		{
			if(mStatus!=MainFrameStatus::Noting)
			{
				wxMessageBox(wxT("请先暂停其他功能"),wxT("操作错误"),wxICON_INFORMATION | wxOK);
				return false;
			}
			sliderPlayControl->Enable(true);
			btnVideoPlayControl->Enable(false);
			analyBar->Enable(true);
			panelCameraDisplay->StaticDisplay(true);
		}
		break;
	case MainFrameStatus::Noting:
		{
			switch (mStatus)
			{
			case MainFrameStatus::VideoPlay:
				btnVideoPlayControl->SetLabelText(wxT("开始播放"));
				InfUpdate->Stop();
				break;
			case MainFrameStatus::ImageAnalysis:
				sliderPlayControl->Enable(false);
				btnVideoPlayControl->Enable(true);
				analyBar->Enable(false);
				panelCameraDisplay->StaticDisplay(false);
				break;
			default:
				btnUpdateDir->Enable(false);
				btnCameraShot->Enable(false);
				listVideoList->Enable(true);
				sliderPlayControl->Enable(false);
				analyBar->Enable(false);
				panelCameraControl->Enable(false);
				break;
			}
		}
		break;
	default:
		wxMessageBox(wxT("未知的程序状态"),wxT("内部错误"),wxICON_ERROR | wxOK);
		return false;
	}
	//更新一下状态
	mStatus=newStatus;
	return true;
}


void on_VideoPlayFinish(void * target)
{
	((MainFrame*)target)->playEngine->Reset(((MainFrame*)target)->currentVideoFile);
	((MainFrame*)target)->btnVideoPlayControl->SetLabel("开始播放");
	((MainFrame*)target)->setStatus(MainFrameStatus::Noting);
}


void MainFrame::on_btnRefreshDevice_click(wxCommandEvent& event)
{
	listDeviceList->ClearAll();
	listDeviceList->InsertColumn(0, wxT("序号"));
	listDeviceList->InsertColumn(1, wxT("设备名称"));
	listDeviceList->InsertColumn(2, wxT("设备UUID"));
	auto device_list=CameraDriver->GetDeviceList();
	int deviceCount = 0;
	for (const DeviceInf& i : device_list)
	{
		wxListItem newItem;
		newItem.SetId(deviceCount);
		newItem.SetColumn(0);
		newItem.SetText(wxString() << deviceCount);
		listDeviceList->InsertItem(newItem);
		newItem.SetColumn(1);
		newItem.SetText(i.DisplayName);
		listDeviceList->SetItem(newItem);
		newItem.SetColumn(2);
		newItem.SetText(i.DeviceID);
		listDeviceList->SetItem(newItem);
		deviceCount++;
	}
}

static int selectIndex = 0; //相机选择状态
void MainFrame::on_btnOpenCloseDevice_click(wxCommandEvent& event)
{
	switch (mStatus)
	{
	case MainFrameStatus::Noting:
		//打开一个相机
		if (listDeviceList->GetSelectedItemCount() > 0)
		{
			try
			{
				devicePtr=CameraDriver->OpenIndexCamera(selectIndex+1, panelCameraDisplay,wxID_ANY); //这里索引从1开始
				devicePtr->SetLinkLimit(false); //关闭链路带宽限制
        devicePtr->GetImageFormat(); //获取图像格式
				panelCameraControl->SetCameraDevice(devicePtr);  //将相机对象给控制板
				btnOpenCloseDevice->SetLabelText(wxT("关闭相机"));
				setStatus(MainFrameStatus::CameraRunning);
			}
			catch (const std::exception& e)
			{
				wxMessageBox(e.what(), wxT("相机打开异常"));
			}
		}
		else
		{
			wxMessageBox(wxT("请先选择一个相机"),wxT("消息"),wxICON_INFORMATION | wxOK);
		}
		break;
	case MainFrameStatus::CameraRunning:
		{
			CameraDriver->CloseCamera(devicePtr);
			btnOpenCloseDevice->SetLabelText(wxT("打开相机"));
			setStatus(MainFrameStatus::Noting);
		}
		break;
	case MainFrameStatus::ImageCollege:
		{
			wxMessageBox(wxT("请先停止存图"),wxT("错误"),wxICON_ERROR | wxOK);
		}
		break;
	default:
		{
			wxMessageBox(wxT("请先暂停其他操作"),wxT("错误"),wxICON_ERROR | wxOK);
		}
		break;
	}
}

void MainFrame::on_listDeviceList_select(wxListEvent& event)
{
	selectIndex=event.GetIndex();
}

void MainFrame::on_dirpSaveDir_change(wxFileDirPickerEvent& event)
{
	saveFile.SetSavePath(dirpSaveDir->GetPath().ToStdString());
	btnUpdateDir->Enable();
	checkImageSaveFunc();
	auto updateEvent = wxCommandEvent(wxEVT_BUTTON, (int)MainFrameID::btnUpdateDir);
	ProcessEvent(updateEvent);
}

void MainFrame::on_btnControlCollege_click(wxCommandEvent& event)
{
	if (!devicePtr->GetSaveImageStatus())
	{
		std::string currentPath = dirpSaveDir->GetTextCtrl()->GetLineText(0).ToStdString();
		if(currentPath.length()>0)
			devicePtr->SetImageSavePath(currentPath);
		currentVideoFile = devicePtr->StartSaveImage();
		btnControlCollege->SetLabelText(wxT("停止存图"));
	}
	else
	{
		devicePtr->StopSaveImage();
		btnControlCollege->SetLabelText(wxT("开始存图"));
		//刷新一下目录
		auto updateEvent = wxCommandEvent(wxEVT_BUTTON, (int)MainFrameID::btnUpdateDir);
		ProcessEvent(updateEvent);
	}
}

void MainFrame::on_InfUpdate_timeout(wxTimerEvent& event)
{
	if (mStatus==MainFrameStatus::ImageCollege)
	{
		txtInf->SetLabelText(wxString::FromUTF8(fmt::format("采集图片数:{},队列长度:{}\n无法保存图片数:{},处理时间:{}",devicePtr->GetReceiveImageNum(),devicePtr->GetQueueLength(), devicePtr->GetUnableSaveImageNum(), devicePtr->GetHandleTime())));
		panelCameraControl->UpdateFrameRate();
		panelCameraControl->UpdateSpeedLink();
	}
	if(mStatus==MainFrameStatus::VideoPlay)
	{
		txtPlayFrameCount->SetLabel(fmt::format("{}/{}", playEngine->GetPos(), playEngine->GetAllFrame()));
		sliderPlayControl->SetValue(playEngine->GetPos());
	}
}

void MainFrame::on_btnVideoPlayControl_click(wxCommandEvent& event)
{
	switch (mStatus)
	{
	case MainFrameStatus::Noting :
		{
			if(currentVideoFile.length()==0)
			{
				wxMessageBox(wxT("请选择有效文件"),wxT("错误"),wxICON_INFORMATION | wxOK);
				return;
			}
			std::string fileComp = playEngine->GetFileName();
			if(fileComp!=currentVideoFile)
				playEngine->Reset(currentVideoFile);
			playEngine->Play();
			setStatus(MainFrameStatus::VideoPlay);
		}
		break;
	case MainFrameStatus::VideoPlay:
		{
			playEngine->Pause();
			setStatus(MainFrameStatus::Noting);
		}
		break;
	default:
		wxMessageBox(wxT("请先关闭相机再播放"), wxT("错误"),wxOK | wxICON_ERROR);
		break;
	}
}

void MainFrame::on_listVideoList_select(wxListEvent& event)
{
	auto i = event.GetItem();
	txtInf->SetLabelText(wxString("已选择文件")+i.GetText());
	currentVideoFile = i.GetText().ToStdString();
	if(mStatus==MainFrameStatus::ImageAnalysis)
	{
		playEngine->Reset(currentVideoFile); //这是设计上的一个缺陷，因为playEngine和AnalyControl共用一个savefile对象，但是这个对象不归MainFrame管理
		wxCommandEvent evt(wxEVT_RADIOBUTTON,(int)MainFrameID::radioAnalyMode);
		ProcessWindowEvent(evt);
	}
	//playEngine->Reset(i.GetText().ToStdString());
}

void MainFrame::on_btnUpdateDir_click(wxCommandEvent& event)
{
	if (dirpSaveDir->GetTextCtrl()->GetLineLength(0) == 0) return;
	listVideoList->ClearAll();
	listVideoList->AppendColumn(wxT("文件名"));
	listVideoList->SetColumnWidth(0, listVideoList->GetSize().GetWidth());
	using namespace std::filesystem;
	path dirPath(dirpSaveDir->GetPath().ToStdString());
	if (!exists(dirPath)) return;
	directory_iterator dirEntry(dirPath);
	int count = 0;
	for (auto& it : dirEntry)
	{
		if (it.status().type() == file_type::regular)
		{
			std::string sfileName = it.path().filename().string();
			if (!std::strcmp(sfileName.substr(sfileName.size() - 4, 4).c_str(),".ccs"))
			{
				listVideoList->InsertItem(0, sfileName);
				count++;
			}
		}
	}
}

void MainFrame::on_sliderPlaySpeedControl_change(wxScrollEvent& event) 
{
	int value = 30 + 10 * sliderPlaySpeedControl->GetValue();
	playEngine->SetFrameRate(value);
	txtPlayFrameInf->SetLabel(wxString().Format("%d FPS", value));
}

void MainFrame::on_sliderPlayControl_change(wxScrollEvent& event)
{
	int i=event.GetPosition();
	if(mStatus==MainFrameStatus::VideoPlay)
	{
		wxCommandEvent evt(wxEVT_BUTTON,(int)MainFrameID::btnVideoPlayControl);
		ProcessEvent(evt);
		playEngine->SetPos(i);
	}
	else if(mStatus==MainFrameStatus::Noting)
	{
		playEngine->SetPos(i);
	}
	else if(mStatus==MainFrameStatus::ImageAnalysis)
	{
		saveFile.SetFramePos(i);
		unsigned char* imgRaw=saveFile.ReadImage();
		wxSize ss=saveFile.GetImageSize();
		analyBar->SetImageData(imgRaw,ss.GetHeight(),ss.GetWidth());
		delete [] imgRaw;
	}
	txtPlayFrameCount->SetLabelText(fmt::format("{}/{}",i,saveFile.GetImageCount()));
}

void MainFrame::on_btnOutputToBMP_click(wxCommandEvent& event)
{
	if(listVideoList->GetSelectedItemCount()==0)
	{
		wxMessageBox(wxT("请先选择一个视频或打开视频存放目录"),wxT("错误"));
		return;
	}
	SaveFile outFile;
	outFile.SetSavePath(dirpSaveDir->GetTextCtrl()->GetLineText(0).ToStdString());
	outFile.DecompressionFile(currentVideoFile,this);
}

void MainFrame::on_btnCameraShot_click(wxCommandEvent& event)
{
	switch (mStatus)
	{
	case MainFrameStatus::CameraRunning:
		try
		{
			devicePtr->SetImageFPSControl(true);
			devicePtr->StartCollegeImage();
		}
		catch(const cameraDriverException& e)
		{
			wxMessageBox(wxString().FromUTF8(e.what()),wxT("相机错误"),wxICON_INFORMATION | wxOK);
			return;
		}
		setStatus(MainFrameStatus::ImageCollege);
		break;
	case MainFrameStatus::ImageCollege:
		if(devicePtr->GetSaveImageStatus())
		{
			wxMessageBox(wxT("请先停止采集图像"),wxT("消息"),wxICON_INFORMATION | wxOK);
			return;
		}
		devicePtr->StopCollegeImage();
		setStatus(MainFrameStatus::CameraRunning);
	default:
		break;
	}
	checkImageSaveFunc();
}

void MainFrame::checkImageSaveFunc()
{
	if(mStatus==MainFrameStatus::ImageCollege && !dirpSaveDir->GetPath().IsEmpty())
		btnControlCollege->Enable(true);
	else 
		btnControlCollege->Enable(false);
}

void MainFrame::on_radioAnalyMode_click(wxCommandEvent& event)
{
	if(checkFileReady())
	{
		setStatus(MainFrameStatus::ImageAnalysis);
		saveFile.SetFramePos(sliderPlayControl->GetValue());
		unsigned char* imgRaw=saveFile.ReadImage();
		wxSize ss=saveFile.GetImageSize();
		analyBar->SetImageData(imgRaw,ss.GetHeight(),ss.GetWidth());
		delete [] imgRaw;
		analyBar->SetHandleArea(saveFile.GetImageSize());
	}
	else
	{
		radioAnalyMode->SetValue(false);
		radioPlayMode->SetValue(true);
		wxMessageBox(wxT("请选择一个文件或打开一个文件夹"),wxT("操作错误"),wxICON_ERROR | wxOK);
	}
}

void MainFrame::on_radioPlayMode_click(wxCommandEvent& event)
{
	if(currentVideoFile.length()==0 || listVideoList->GetSelectedItemCount()==0)
	{
		radioAnalyMode->SetValue(true);
		radioPlayMode->SetValue(false);
		wxMessageBox(wxT("请选择一个文件或打开一个文件夹"),wxT("操作错误"),wxICON_ERROR | wxOK);
		return;
	}
	playEngine->Reset(currentVideoFile);
	sliderPlayControl->SetValue(0);
	setStatus(MainFrameStatus::Noting);
}

void MainFrame::checkFilePlayAnalyizeFunc()
{
	
}

bool MainFrame::checkFileReady()
{
	if(currentVideoFile.length()==0 || listVideoList->GetSelectedItemCount()==0)
		return false;
	if(saveFile.GetFileOpenStatus())
		saveFile.StopReadImage();
	int32_t imgW,imgH,imgCount;
  pixelFormat imgFormat;
	saveFile.StartReadImage(currentVideoFile,imgW,imgH,imgCount,imgFormat);
	sliderPlayControl->SetRange(0,imgCount);
	return true;
}

void MainFrame::emitPlayEngineFinish()
{
	if(mStatus==MainFrameStatus::VideoPlay)
		QueueEvent(new wxCommandEvent(wxEVT_BUTTON,(int)MainFrameID::btnVideoPlayControl));
}

void MainFrame::emitSetPlayPos(int pos)
{
	if(mStatus==MainFrameStatus::ImageAnalysis)
		QueueEvent(new wxScrollEvent(wxEVT_SCROLL_CHANGED,(int)MainFrameID::sliderPlayControl,pos,0));
}

void MainFrame::on_btnRemoteSetting_click(wxCommandEvent& event)
{
	panelCameraDisplay->SetRemoteParameter();
}

void MainFrame::on_cboxRemoteMonitor_click(wxCommandEvent& event)
{
	if(!panelCameraDisplay->SetRemoterMirror(cboxRemoteMonitor->GetValue()))
		cboxRemoteMonitor->SetValue(false);
}

void MainFrame::on_RemoteGetStatus(wxCommandEvent& event)
{
	int32_t value;
	if(RemoteCommandErrorFlag)
	{
		RemoteCommandErrorFlag=false;
		value=0x0;
	}
	else
	{
		switch (mStatus)
		{
		case MainFrameStatus::Noting:
			value=0x1;
			break;
		case MainFrameStatus::CameraRunning:
			value=0x3;
			break;
		case MainFrameStatus::ImageCollege:
			if(devicePtr->GetSaveImageStatus())
				value=0x5;
			else
				value=0x4;
			break;
		default:
			value=0x0;
			break;
		}
	}
	remoteHandle.SendDeviceStatus(value);
}

void MainFrame::on_RemoteStartShot(wxCommandEvent& event)
{
	if(!CheckStatus(MainFrameStatus::CameraRunning)) return;
	wxCommandEvent btnEvent;
	on_btnCameraShot_click(btnEvent);
}

void MainFrame::on_RemoteStopShot(wxCommandEvent& event)
{
	wxCommandEvent btnEvent;
	if(!CheckStatus(MainFrameStatus::ImageCollege)) return;
	on_btnCameraShot_click(btnEvent);
}

void MainFrame::on_RemoteInitDevice(wxCommandEvent& event)
{
	wxCommandEvent btnEvent;
	on_btnRefreshDevice_click(btnEvent);
	if(listDeviceList->GetItemCount()==0)
	{
		remoteHandle.SendMessage("找不到任何相机");
		return;
	}
	listDeviceList->SetItemState(0,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED);
	wxListEvent listEvt;
	listEvt.SetIndex(0);
	on_listDeviceList_select(listEvt);
	on_btnOpenCloseDevice_click(btnEvent);
	CheckStatus(MainFrameStatus::CameraRunning);
}

void MainFrame::on_RemoteStartSave(wxCommandEvent& event)
{
	if(mStatus!=MainFrameStatus::ImageCollege || devicePtr->GetCollegeImageStatus()==false)
	{
		remoteHandle.SendMessage("相机处于非法状态");
		RemoteCommandErrorFlag=true;
		return;
	}
	wxCommandEvent btnEvent;
	on_btnControlCollege_click(btnEvent);
	CheckStatus(MainFrameStatus::ImageCollege);
}

void MainFrame::on_RemoteStopSave(wxCommandEvent& event)
{
	if(!CheckStatus(MainFrameStatus::ImageCollege)) return;
	wxCommandEvent btnEvent;
	on_btnControlCollege_click(btnEvent);
}

void MainFrame::CheckConfigFile()
{
	std::ifstream configFile("./config");
	if(!configFile.is_open())
		return;
	std::string IPAddress,Port,DeviceName;
	configFile>>IPAddress>>Port>>DeviceName;
	if(configFile.good())
	{
		panelCameraDisplay->SetRemoteParameter(IPAddress,Port,DeviceName);
		cboxRemoteMonitor->SetValue(true);
		wxCommandEvent btnEvt;
		on_cboxRemoteMonitor_click(btnEvt);
	}
	configFile.close();
}

void MainFrame::on_RemoteGetCameraPara(wxCommandEvent& event)
{
	if(!CheckStatus(MainFrameStatus::CameraRunning)) return;
	remoteHandle.SendCameraPara({
		static_cast<int32_t>(devicePtr->GetImageHeight()),
		static_cast<int32_t>(devicePtr->GetImageWidth()),
		static_cast<int32_t>(devicePtr->GetImageOffsetX()),
		static_cast<int32_t>(devicePtr->GetImageOffsetY()),
		static_cast<int32_t>(devicePtr->GetExposureTime()),
		static_cast<int32_t>(panelCameraControl->GetFrameRate()),  //这是因为驱动程序不能直接读取限制帧率，只能读取实时帧率
		devicePtr->GetTriggerMode() ? 0x1 : 0x0
	});
}

void MainFrame::on_RemoteEnableTriggerMode(wxCommandEvent& event)
{
	panelCameraControl->SetTriggerMode(true);
}

void MainFrame::on_RemoteDisableTriggerMode(wxCommandEvent& event)
{
	panelCameraControl->SetTriggerMode(false);
}

void MainFrame::on_RemoteSetExposeTime(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetExposeTime(event.GetParament());});
}

void MainFrame::on_RemoteSetImageHeight(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetImageHeight(event.GetParament());});
}

void MainFrame::on_RemoteSetImageWidth(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetImageWidth(event.GetParament());});
}

void MainFrame::on_RemoteSetOffsetX(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetImageOffsetX(event.GetParament());});
}

void MainFrame::on_RemoteSetOffsetY(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetImageOffsetY(event.GetParament());});
}

void MainFrame::on_RemoteSetFrameRate(RemoteCommandAndParament& event)
{
	CheckCameraParamentSetting([&]{panelCameraControl->SetFrameRate(event.GetParament());});
}

void MainFrame::CheckCameraParamentSetting(const std::function<void()>& func)
{
	try
	{
		func();
	}
	catch(const std::exception& e)
	{
		remoteHandle.SendMessage(e.what());
		RemoteCommandErrorFlag=true;
	}
}

inline bool MainFrame::CheckStatus(const MainFrameStatus targetStatus)
{
	if(mStatus!=targetStatus)
	{
		remoteHandle.SendMessage("相机处于非法状态");
		RemoteCommandErrorFlag=true;
		return false;
	}
	return true;
}

bool MainFrame::GetServerLinkStatus()
{
	return cboxRemoteMonitor->GetValue();
}

void MainFrame::on_RemoteFileTransferEnable(wxCommandEvent& event)
{
	msgFileTransfer->ShowModal();
}

void MainFrame::on_RemoteFileTransferDisable(wxCommandEvent& event)
{
	msgFileTransfer->Close();
}

void MainFrame::on_RemoteFileTransferRequest(wxCommandEvent& event)
{
	if(currentVideoFile.length()==0 || dirpSaveDir->GetPath().length()==0)
	{
		remoteHandle.StopFileTransfer();
		return;
	}
	remoteHandle.FileTransfer(fmt::format("{}/{}",dirpSaveDir->GetPath().ToStdString(),currentVideoFile));
}
